home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65 / src / deliver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  32.1 KB  |  1,519 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted provided
  7.  * that: (1) source distributions retain this entire copyright notice and
  8.  * comment, and (2) distributions including binaries display the following
  9.  * acknowledgement:  ``This product includes software developed by the
  10.  * University of California, Berkeley and its contributors'' in the
  11.  * documentation or other materials provided with the distribution and in
  12.  * all advertising materials mentioning features or use of this software.
  13.  * Neither the name of the University nor the names of its contributors may
  14.  * be used to endorse or promote products derived from this software without
  15.  * specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)deliver.c    5.38 (Berkeley) 6/1/90";
  23. #endif /* not lint */
  24.  
  25. #include "sendmail.h"
  26. #include <sys/signal.h>
  27. #include <sys/stat.h>
  28. #include <netdb.h>
  29. #include <fcntl.h>
  30. #include <errno.h>
  31. #ifdef NAMED_BIND
  32. #include <arpa/nameser.h>
  33. #include <resolv.h>
  34. #endif
  35.  
  36. /*
  37. **  DELIVER -- Deliver a message to a list of addresses.
  38. **
  39. **    This routine delivers to everyone on the same host as the
  40. **    user on the head of the list.  It is clever about mailers
  41. **    that don't handle multiple users.  It is NOT guaranteed
  42. **    that it will deliver to all these addresses however -- so
  43. **    deliver should be called once for each address on the
  44. **    list.
  45. **
  46. **    Parameters:
  47. **        e -- the envelope to deliver.
  48. **        firstto -- head of the address list to deliver to.
  49. **
  50. **    Returns:
  51. **        zero -- successfully delivered.
  52. **        else -- some failure, see ExitStat for more info.
  53. **
  54. **    Side Effects:
  55. **        The standard input is passed off to someone.
  56. */
  57.  
  58. deliver(e, firstto)
  59.     register ENVELOPE *e;
  60.     ADDRESS *firstto;
  61. {
  62.     char *host;            /* host being sent to */
  63.     char *user;            /* user being sent to */
  64.     char **pvp;
  65.     register char **mvp;
  66.     register char *p;
  67.     register MAILER *m;        /* mailer for this recipient */
  68.     ADDRESS *ctladdr;
  69.     register ADDRESS *to = firstto;
  70.     bool clever = FALSE;        /* running user smtp to this mailer */
  71.     ADDRESS *tochain = NULL;    /* chain of users in this mailer call */
  72.     int rcode;        /* response code */
  73.     char *pv[MAXPV+1];
  74.     char tobuf[MAXLINE-50];        /* text line of to people */
  75.     char buf[MAXNAME];
  76.     char tfrombuf[MAXNAME];        /* translated from person */
  77.     extern bool checkcompat();
  78.     extern ADDRESS *getctladdr();
  79.     extern char *remotename();
  80.  
  81.     errno = 0;
  82.     if (bitset(QDONTSEND, to->q_flags))
  83.         return (0);
  84.  
  85. #ifdef NAMED_BIND
  86.     /* unless interactive, try twice, over a minute */
  87.     if (OpMode == MD_DAEMON || OpMode == MD_SMTP) {
  88.         _res.retrans = 30;
  89.         _res.retry = 2;
  90.     }
  91. #endif 
  92.  
  93.     m = to->q_mailer;
  94.     host = to->q_host;
  95.  
  96.     if (tTd(10, 1))
  97.         printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
  98.             m->m_mno, host, to->q_user);
  99.  
  100.     /*
  101.     **  If this mailer is expensive, and if we don't want to make
  102.     **  connections now, just mark these addresses and return.
  103.     **    This is useful if we want to batch connections to
  104.     **    reduce load.  This will cause the messages to be
  105.     **    queued up, and a daemon will come along to send the
  106.     **    messages later.
  107.     **        This should be on a per-mailer basis.
  108.     */
  109.  
  110.     if (NoConnect && !QueueRun && bitnset(M_EXPENSIVE, m->m_flags) &&
  111.         !Verbose)
  112.     {
  113.         for (; to != NULL; to = to->q_next)
  114.         {
  115.             if (bitset(QDONTSEND, to->q_flags) || to->q_mailer != m)
  116.                 continue;
  117.             to->q_flags |= QQUEUEUP|QDONTSEND;
  118.             e->e_to = to->q_paddr;
  119.             message(Arpa_Info, "queued");
  120.             if (LogLevel > 4)
  121.                 logdelivery("queued");
  122.         }
  123.         e->e_to = NULL;
  124.         return (0);
  125.     }
  126.  
  127.     /*
  128.     **  Do initial argv setup.
  129.     **    Insert the mailer name.  Notice that $x expansion is
  130.     **    NOT done on the mailer name.  Then, if the mailer has
  131.     **    a picky -f flag, we insert it as appropriate.  This
  132.     **    code does not check for 'pv' overflow; this places a
  133.     **    manifest lower limit of 4 for MAXPV.
  134.     **        The from address rewrite is expected to make
  135.     **        the address relative to the other end.
  136.     */
  137.  
  138.     /* rewrite from address, using rewriting rules */
  139.     expand("\001f", buf, &buf[sizeof buf - 1], e);
  140.     (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE));
  141.  
  142.     define('g', tfrombuf, e);        /* translated sender address */
  143.     define('h', host, e);            /* to host */
  144.     Errors = 0;
  145.     pvp = pv;
  146.     *pvp++ = m->m_argv[0];
  147.  
  148.     /* insert -f or -r flag as appropriate */
  149.     if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
  150.     {
  151.         if (bitnset(M_FOPT, m->m_flags))
  152.             *pvp++ = "-f";
  153.         else
  154.             *pvp++ = "-r";
  155.         expand("\001g", buf, &buf[sizeof buf - 1], e);
  156.         *pvp++ = newstr(buf);
  157.     }
  158.  
  159.     /*
  160.     **  Append the other fixed parts of the argv.  These run
  161.     **  up to the first entry containing "$u".  There can only
  162.     **  be one of these, and there are only a few more slots
  163.     **  in the pv after it.
  164.     */
  165.  
  166.     for (mvp = m->m_argv; (p = *++mvp) != NULL; )
  167.     {
  168.         while ((p = index(p, '\001')) != NULL)
  169.             if (*++p == 'u')
  170.                 break;
  171.         if (p != NULL)
  172.             break;
  173.  
  174.         /* this entry is safe -- go ahead and process it */
  175.         expand(*mvp, buf, &buf[sizeof buf - 1], e);
  176.         *pvp++ = newstr(buf);
  177.         if (pvp >= &pv[MAXPV - 3])
  178.         {
  179.             syserr("Too many parameters to %s before $u", pv[0]);
  180.             return (-1);
  181.         }
  182.     }
  183.  
  184.     /*
  185.     **  If we have no substitution for the user name in the argument
  186.     **  list, we know that we must supply the names otherwise -- and
  187.     **  SMTP is the answer!!
  188.     */
  189.  
  190.     if (*mvp == NULL)
  191.     {
  192.         /* running SMTP */
  193. # ifdef SMTP
  194.         clever = TRUE;
  195.         *pvp = NULL;
  196. # else SMTP
  197.         /* oops!  we don't implement SMTP */
  198.         syserr("SMTP style mailer");
  199.         return (EX_SOFTWARE);
  200. # endif SMTP
  201.     }
  202.  
  203.     /*
  204.     **  At this point *mvp points to the argument with $u.  We
  205.     **  run through our address list and append all the addresses
  206.     **  we can.  If we run out of space, do not fret!  We can
  207.     **  always send another copy later.
  208.     */
  209.  
  210.     tobuf[0] = '\0';
  211.     e->e_to = tobuf;
  212.     ctladdr = NULL;
  213.     for (; to != NULL; to = to->q_next)
  214.     {
  215.         /* avoid sending multiple recipients to dumb mailers */
  216.         if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
  217.             break;
  218.  
  219.         /* if already sent or not for this host, don't send */
  220.         if (bitset(QDONTSEND, to->q_flags) ||
  221.             strcmp(to->q_host, host) != 0 ||
  222.             to->q_mailer != firstto->q_mailer)
  223.             continue;
  224.  
  225.         /* avoid overflowing tobuf */
  226.         if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2))
  227.             break;
  228.  
  229.         if (tTd(10, 1))
  230.         {
  231.             printf("\nsend to ");
  232.             printaddr(to, FALSE);
  233.         }
  234.  
  235.         /* compute effective uid/gid when sending */
  236.         if (to->q_mailer == ProgMailer)
  237.             ctladdr = getctladdr(to);
  238.  
  239.         user = to->q_user;
  240.         e->e_to = to->q_paddr;
  241.         to->q_flags |= QDONTSEND;
  242.  
  243.         /*
  244.         **  Check to see that these people are allowed to
  245.         **  talk to each other.
  246.         */
  247.  
  248.         if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
  249.         {
  250.             NoReturn = TRUE;
  251.             usrerr("Message is too large; %ld bytes max", m->m_maxsize);
  252.             giveresponse(EX_UNAVAILABLE, m, e);
  253.             continue;
  254.         }
  255.         if (!checkcompat(to))
  256.         {
  257.             giveresponse(EX_UNAVAILABLE, m, e);
  258.             continue;
  259.         }
  260.  
  261.         /*
  262.         **  Strip quote bits from names if the mailer is dumb
  263.         **    about them.
  264.         */
  265.  
  266.         if (bitnset(M_STRIPQ, m->m_flags))
  267.         {
  268.             stripquotes(user, TRUE);
  269.             stripquotes(host, TRUE);
  270.         }
  271.         else
  272.         {
  273.             stripquotes(user, FALSE);
  274.             stripquotes(host, FALSE);
  275.         }
  276.  
  277.         /* hack attack -- delivermail compatibility */
  278.         if (m == ProgMailer && *user == '|')
  279.             user++;
  280.  
  281.         /*
  282.         **  If an error message has already been given, don't
  283.         **    bother to send to this address.
  284.         **
  285.         **    >>>>>>>>>> This clause assumes that the local mailer
  286.         **    >> NOTE >> cannot do any further aliasing; that
  287.         **    >>>>>>>>>> function is subsumed by sendmail.
  288.         */
  289.  
  290.         if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
  291.             continue;
  292.  
  293.         /* save statistics.... */
  294.         markstats(e, to);
  295.  
  296.         /*
  297.         **  See if this user name is "special".
  298.         **    If the user name has a slash in it, assume that this
  299.         **    is a file -- send it off without further ado.  Note
  300.         **    that this type of addresses is not processed along
  301.         **    with the others, so we fudge on the To person.
  302.         */
  303.  
  304.         if (m == LocalMailer)
  305.         {
  306.             if (user[0] == '/')
  307.             {
  308.                 rcode = mailfile(user, getctladdr(to));
  309.                 giveresponse(rcode, m, e);
  310.                 continue;
  311.             }
  312.         }
  313.  
  314.         /*
  315.         **  Address is verified -- add this user to mailer
  316.         **  argv, and add it to the print list of recipients.
  317.         */
  318.  
  319.         /* link together the chain of recipients */
  320.         to->q_tchain = tochain;
  321.         tochain = to;
  322.  
  323.         /* create list of users for error messages */
  324.         (void) strcat(tobuf, ",");
  325.         (void) strcat(tobuf, to->q_paddr);
  326.         define('u', user, e);        /* to user */
  327.         define('z', to->q_home, e);    /* user's home */
  328.  
  329.         /*
  330.         **  Expand out this user into argument list.
  331.         */
  332.  
  333.         if (!clever)
  334.         {
  335.             expand(*mvp, buf, &buf[sizeof buf - 1], e);
  336.             *pvp++ = newstr(buf);
  337.             if (pvp >= &pv[MAXPV - 2])
  338.             {
  339.                 /* allow some space for trailing parms */
  340.                 break;
  341.             }
  342.         }
  343.     }
  344.  
  345.     /* see if any addresses still exist */
  346.     if (tobuf[0] == '\0')
  347.     {
  348.         define('g', (char *) NULL, e);
  349.         return (0);
  350.     }
  351.  
  352.     /* print out messages as full list */
  353.     e->e_to = tobuf + 1;
  354.  
  355.     /*
  356.     **  Fill out any parameters after the $u parameter.
  357.     */
  358.  
  359.     while (!clever && *++mvp != NULL)
  360.     {
  361.         expand(*mvp, buf, &buf[sizeof buf - 1], e);
  362.         *pvp++ = newstr(buf);
  363.         if (pvp >= &pv[MAXPV])
  364.             syserr("deliver: pv overflow after $u for %s", pv[0]);
  365.     }
  366.     *pvp++ = NULL;
  367.  
  368.     /*
  369.     **  Call the mailer.
  370.     **    The argument vector gets built, pipes
  371.     **    are created as necessary, and we fork & exec as
  372.     **    appropriate.
  373.     **    If we are running SMTP, we just need to clean up.
  374.     */
  375.  
  376.     if (ctladdr == NULL)
  377.         ctladdr = &e->e_from;
  378. #ifdef NAMED_BIND
  379.     _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);        /* XXX */
  380. #endif
  381. #ifdef SMTP
  382.     if (clever)
  383.     {
  384.         rcode = EX_OK;
  385. #ifdef NAMED_BIND
  386.         if (host[0] && host[0] != '[')
  387.         {
  388.             expand("\001w", buf, &buf[sizeof(buf) - 1], e);
  389.             Nmx = getmxrr(host, MxHosts, buf, &rcode);
  390.         }
  391.         else
  392. #endif
  393.         {
  394.             Nmx = 1;
  395.             MxHosts[0] = host;
  396.         }
  397.         if (Nmx >= 0)
  398.         {
  399.             message(Arpa_Info, "Connecting to %s (%s)...",
  400.                 MxHosts[0], m->m_name);
  401.             if ((rcode = smtpinit(m, pv)) == EX_OK) {
  402.                 register char *t = tobuf;
  403.                 register int i;
  404.  
  405.                 /* send the recipient list */
  406.                 tobuf[0] = '\0';
  407.                 for (to = tochain; to; to = to->q_tchain) {
  408.                     e->e_to = to->q_paddr;
  409.                     if ((i = smtprcpt(to, m)) != EX_OK) {
  410.                         markfailure(e, to, i);
  411.                         giveresponse(i, m, e);
  412.                     }
  413.                     else {
  414.                         *t++ = ',';
  415.                         for (p = to->q_paddr; *p; *t++ = *p++);
  416.                     }
  417.                 }
  418.  
  419.                 /* now send the data */
  420.                 if (tobuf[0] == '\0')
  421.                     e->e_to = NULL;
  422.                 else {
  423.                     e->e_to = tobuf + 1;
  424.                     rcode = smtpdata(m, e);
  425.                 }
  426.  
  427.                 /* now close the connection */
  428.                 smtpquit(m);
  429.             }
  430.         }
  431.     }
  432.     else
  433. #endif /* SMTP */
  434.     {
  435.         message(Arpa_Info, "Connecting to %s (%s)...", host, m->m_name);
  436.         rcode = sendoff(e, m, pv, ctladdr);
  437.     }
  438. #ifdef NAMED_BIND
  439.     _res.options |= RES_DEFNAMES | RES_DNSRCH;    /* XXX */
  440. #endif
  441.  
  442.     /*
  443.     **  Do final status disposal.
  444.     **    We check for something in tobuf for the SMTP case.
  445.     **    If we got a temporary failure, arrange to queue the
  446.     **        addressees.
  447.     */
  448.  
  449.     if (tobuf[0] != '\0')
  450.         giveresponse(rcode, m, e);
  451.     if (rcode != EX_OK)
  452.         for (to = tochain; to != NULL; to = to->q_tchain)
  453.             markfailure(e, to, rcode);
  454.  
  455.     errno = 0;
  456.     define('g', (char *) NULL, e);
  457.     return (rcode);
  458. }
  459. /*
  460. **  MARKFAILURE -- mark a failure on a specific address.
  461. **
  462. **    Parameters:
  463. **        e -- the envelope we are sending.
  464. **        q -- the address to mark.
  465. **        rcode -- the code signifying the particular failure.
  466. **
  467. **    Returns:
  468. **        none.
  469. **
  470. **    Side Effects:
  471. **        marks the address (and possibly the envelope) with the
  472. **            failure so that an error will be returned or
  473. **            the message will be queued, as appropriate.
  474. */
  475.  
  476. markfailure(e, q, rcode)
  477.     register ENVELOPE *e;
  478.     register ADDRESS *q;
  479.     int rcode;
  480. {
  481.     if (rcode == EX_OK)
  482.         return;
  483.     else if (rcode != EX_TEMPFAIL && rcode != EX_IOERR && rcode != EX_OSERR)
  484.         q->q_flags |= QBADADDR;
  485.     else if (curtime() > e->e_ctime + TimeOut)
  486.     {
  487.         extern char *pintvl();
  488.         char buf[MAXLINE];
  489.  
  490.         if (!bitset(EF_TIMEOUT, e->e_flags))
  491.         {
  492.             (void) sprintf(buf, "Cannot send message for %s",
  493.                 pintvl(TimeOut, FALSE));
  494.             if (e->e_message != NULL)
  495.                 free(e->e_message);
  496.             e->e_message = newstr(buf);
  497.             message(Arpa_Info, buf);
  498.         }
  499.         q->q_flags |= QBADADDR;
  500.         e->e_flags |= EF_TIMEOUT;
  501.     }
  502.     else
  503.         q->q_flags |= QQUEUEUP;
  504. }
  505. /*
  506. **  DOFORK -- do a fork, retrying a couple of times on failure.
  507. **
  508. **    This MUST be a macro, since after a vfork we are running
  509. **    two processes on the same stack!!!
  510. **
  511. **    Parameters:
  512. **        none.
  513. **
  514. **    Returns:
  515. **        From a macro???  You've got to be kidding!
  516. **
  517. **    Side Effects:
  518. **        Modifies the ==> LOCAL <== variable 'pid', leaving:
  519. **            pid of child in parent, zero in child.
  520. **            -1 on unrecoverable error.
  521. **
  522. **    Notes:
  523. **        I'm awfully sorry this looks so awful.  That's
  524. **        vfork for you.....
  525. */
  526.  
  527. # define NFORKTRIES    5
  528. # ifdef VMUNIX
  529. # define XFORK    vfork
  530. # else VMUNIX
  531. # define XFORK    fork
  532. # endif VMUNIX
  533.  
  534. # define DOFORK(fORKfN) \
  535. {\
  536.     register int i;\
  537. \
  538.     for (i = NFORKTRIES; --i >= 0; )\
  539.     {\
  540.         pid = fORKfN();\
  541.         if (pid >= 0)\
  542.             break;\
  543.         if (i > 0)\
  544.             sleep((unsigned) NFORKTRIES - i);\
  545.     }\
  546. }
  547. /*
  548. **  DOFORK -- simple fork interface to DOFORK.
  549. **
  550. **    Parameters:
  551. **        none.
  552. **
  553. **    Returns:
  554. **        pid of child in parent.
  555. **        zero in child.
  556. **        -1 on error.
  557. **
  558. **    Side Effects:
  559. **        returns twice, once in parent and once in child.
  560. */
  561.  
  562. dofork()
  563. {
  564.     register int pid;
  565.  
  566.     DOFORK(fork);
  567.     return (pid);
  568. }
  569. /*
  570. **  SENDOFF -- send off call to mailer & collect response.
  571. **
  572. **    Parameters:
  573. **        e -- the envelope to mail.
  574. **        m -- mailer descriptor.
  575. **        pvp -- parameter vector to send to it.
  576. **        ctladdr -- an address pointer controlling the
  577. **            user/groupid etc. of the mailer.
  578. **
  579. **    Returns:
  580. **        exit status of mailer.
  581. **
  582. **    Side Effects:
  583. **        none.
  584. */
  585. static
  586. sendoff(e, m, pvp, ctladdr)
  587.     register ENVELOPE *e;
  588.     MAILER *m;
  589.     char **pvp;
  590.     ADDRESS *ctladdr;
  591. {
  592.     auto FILE *mfile;
  593.     auto FILE *rfile;
  594.     register int i;
  595.     int pid;
  596.  
  597.     /*
  598.     **  Create connection to mailer.
  599.     */
  600.  
  601.     pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile);
  602.     if (pid < 0)
  603.         return (-1);
  604.  
  605.     /*
  606.     **  Format and send message.
  607.     */
  608.  
  609.     putfromline(mfile, m);
  610.     (*e->e_puthdr)(mfile, m, e);
  611.     putline("\n", mfile, m);
  612.     (*e->e_putbody)(mfile, m, e);
  613.     (void) fclose(mfile);
  614.     if (rfile != NULL)
  615.         (void) fclose(rfile);
  616.  
  617.     i = endmailer(pid, pvp[0]);
  618.  
  619.     /* arrange a return receipt if requested */
  620.     if (e->e_receiptto != NULL && bitnset(M_LOCAL, m->m_flags))
  621.     {
  622.         e->e_flags |= EF_SENDRECEIPT;
  623.         /* do we want to send back more info? */
  624.     }
  625.  
  626.     return (i);
  627. }
  628. /*
  629. **  ENDMAILER -- Wait for mailer to terminate.
  630. **
  631. **    We should never get fatal errors (e.g., segmentation
  632. **    violation), so we report those specially.  For other
  633. **    errors, we choose a status message (into statmsg),
  634. **    and if it represents an error, we print it.
  635. **
  636. **    Parameters:
  637. **        pid -- pid of mailer.
  638. **        name -- name of mailer (for error messages).
  639. **
  640. **    Returns:
  641. **        exit code of mailer.
  642. **
  643. **    Side Effects:
  644. **        none.
  645. */
  646.  
  647. endmailer(pid, name)
  648.     int pid;
  649.     char *name;
  650. {
  651.     int st;
  652.  
  653.     /* in the IPC case there is nothing to wait for */
  654.     if (pid == 0)
  655.         return (EX_OK);
  656.  
  657.     /* wait for the mailer process to die and collect status */
  658.     st = waitfor(pid);
  659.     if (st == -1)
  660.     {
  661.         syserr("endmailer %s: wait", name);
  662.         return (EX_SOFTWARE);
  663.     }
  664.  
  665.     /* see if it died a horrid death */
  666.     if ((st & 0377) != 0)
  667.     {
  668.         syserr("mailer %s died with signal %o", name, st);
  669.         ExitStat = EX_TEMPFAIL;
  670.         return (EX_TEMPFAIL);
  671.     }
  672.  
  673.     /* normal death -- return status */
  674.     st = (st >> 8) & 0377;
  675.     return (st);
  676. }
  677. /*
  678. **  OPENMAILER -- open connection to mailer.
  679. **
  680. **    Parameters:
  681. **        m -- mailer descriptor.
  682. **        pvp -- parameter vector to pass to mailer.
  683. **        ctladdr -- controlling address for user.
  684. **        clever -- create a full duplex connection.
  685. **        pmfile -- pointer to mfile (to mailer) connection.
  686. **        prfile -- pointer to rfile (from mailer) connection.
  687. **
  688. **    Returns:
  689. **        pid of mailer ( > 0 ).
  690. **        -1 on error.
  691. **        zero on an IPC connection.
  692. **
  693. **    Side Effects:
  694. **        creates a mailer in a subprocess.
  695. */
  696.  
  697. openmailer(m, pvp, ctladdr, clever, pmfile, prfile)
  698.     MAILER *m;
  699.     char **pvp;
  700.     ADDRESS *ctladdr;
  701.     bool clever;
  702.     FILE **pmfile;
  703.     FILE **prfile;
  704. {
  705.     int pid;
  706.     int mpvect[2];
  707.     int rpvect[2];
  708.     FILE *mfile = NULL;
  709.     FILE *rfile = NULL;
  710.     extern FILE *fdopen();
  711.  
  712.     if (tTd(11, 1))
  713.     {
  714.         printf("openmailer:");
  715.         printav(pvp);
  716.     }
  717.     errno = 0;
  718.  
  719.     CurHostName = m->m_mailer;
  720.  
  721.     /*
  722.     **  Deal with the special case of mail handled through an IPC
  723.     **  connection.
  724.     **    In this case we don't actually fork.  We must be
  725.     **    running SMTP for this to work.  We will return a
  726.     **    zero pid to indicate that we are running IPC.
  727.     **  We also handle a debug version that just talks to stdin/out.
  728.     */
  729.  
  730.     /* check for Local Person Communication -- not for mortals!!! */
  731.     if (strcmp(m->m_mailer, "[LPC]") == 0)
  732.     {
  733.         *pmfile = stdout;
  734.         *prfile = stdin;
  735.         return (0);
  736.     }
  737.  
  738.     if (strcmp(m->m_mailer, "[IPC]") == 0)
  739.     {
  740. #ifdef HOSTINFO
  741.         register STAB *st;
  742.         extern STAB *stab();
  743. #endif HOSTINFO
  744. #ifdef DAEMON
  745.         register int i, j;
  746.         register u_short port;
  747.  
  748.         CurHostName = pvp[1];
  749.         if (!clever)
  750.             syserr("non-clever IPC");
  751.         if (pvp[2] != NULL)
  752.             port = atoi(pvp[2]);
  753.         else
  754.             port = 0;
  755.         for (j = 0; j < Nmx; j++)
  756.         {
  757.             CurHostName = MxHosts[j];
  758. #ifdef HOSTINFO
  759.         /* see if we have already determined that this host is fried */
  760.             st = stab(MxHosts[j], ST_HOST, ST_FIND);
  761.             if (st == NULL || st->s_host.ho_exitstat == EX_OK) {
  762.                 if (j > 1)
  763.                     message(Arpa_Info,
  764.                         "Connecting to %s (%s)...",
  765.                         MxHosts[j], m->m_name);
  766.                 i = makeconnection(MxHosts[j], port, pmfile, prfile);
  767.             }
  768.             else
  769.             {
  770.                 i = st->s_host.ho_exitstat;
  771.                 errno = st->s_host.ho_errno;
  772.             }
  773. #else HOSTINFO
  774.             i = makeconnection(MxHosts[j], port, pmfile, prfile);
  775. #endif HOSTINFO
  776.             if (i != EX_OK)
  777.             {
  778. #ifdef HOSTINFO
  779.                 /* enter status of this host */
  780.                 if (st == NULL)
  781.                     st = stab(MxHosts[j], ST_HOST, ST_ENTER);
  782.                 st->s_host.ho_exitstat = i;
  783.                 st->s_host.ho_errno = errno;
  784. #endif HOSTINFO
  785.                 ExitStat = i;
  786.                 continue;
  787.             }
  788.             else
  789.                 return (0);
  790.         }
  791.         return (-1);
  792. #else DAEMON
  793.         syserr("openmailer: no IPC");
  794.         return (-1);
  795. #endif DAEMON
  796.     }
  797.  
  798.     /* create a pipe to shove the mail through */
  799.     if (pipe(mpvect) < 0)
  800.     {
  801.         syserr("openmailer: pipe (to mailer)");
  802.         return (-1);
  803.     }
  804.  
  805. #ifdef SMTP
  806.     /* if this mailer speaks smtp, create a return pipe */
  807.     if (clever && pipe(rpvect) < 0)
  808.     {
  809.         syserr("openmailer: pipe (from mailer)");
  810.         (void) close(mpvect[0]);
  811.         (void) close(mpvect[1]);
  812.         return (-1);
  813.     }
  814. #endif SMTP
  815.  
  816.     /*
  817.     **  Actually fork the mailer process.
  818.     **    DOFORK is clever about retrying.
  819.     **
  820.     **    Dispose of SIGCHLD signal catchers that may be laying
  821.     **    around so that endmail will get it.
  822.     */
  823.  
  824.     if (CurEnv->e_xfp != NULL)
  825.         (void) fflush(CurEnv->e_xfp);        /* for debugging */
  826.     (void) fflush(stdout);
  827. # ifdef SIGCHLD
  828.     (void) signal(SIGCHLD, SIG_DFL);
  829. # endif SIGCHLD
  830.     DOFORK(XFORK);
  831.     /* pid is set by DOFORK */
  832.     if (pid < 0)
  833.     {
  834.         /* failure */
  835.         syserr("openmailer: cannot fork");
  836.         (void) close(mpvect[0]);
  837.         (void) close(mpvect[1]);
  838. #ifdef SMTP
  839.         if (clever)
  840.         {
  841.             (void) close(rpvect[0]);
  842.             (void) close(rpvect[1]);
  843.         }
  844. #endif SMTP
  845.         return (-1);
  846.     }
  847.     else if (pid == 0)
  848.     {
  849.         int i;
  850.         extern int DtableSize;
  851.  
  852.         /* child -- set up input & exec mailer */
  853.         /* make diagnostic output be standard output */
  854.         (void) signal(SIGINT, SIG_IGN);
  855.         (void) signal(SIGHUP, SIG_IGN);
  856.         (void) signal(SIGTERM, SIG_DFL);
  857.  
  858.         /* arrange to filter standard & diag output of command */
  859.         if (clever)
  860.         {
  861.             (void) close(rpvect[0]);
  862.             (void) close(1);
  863.             (void) dup(rpvect[1]);
  864.             (void) close(rpvect[1]);
  865.         }
  866.         else if (OpMode == MD_SMTP || HoldErrs)
  867.         {
  868.             /* put mailer output in transcript */
  869.             (void) close(1);
  870.             (void) dup(fileno(CurEnv->e_xfp));
  871.         }
  872.         (void) close(2);
  873.         (void) dup(1);
  874.  
  875.         /* arrange to get standard input */
  876.         (void) close(mpvect[1]);
  877.         (void) close(0);
  878.         if (dup(mpvect[0]) < 0)
  879.         {
  880.             syserr("Cannot dup to zero!");
  881.             _exit(EX_OSERR);
  882.         }
  883.         (void) close(mpvect[0]);
  884.         if (!bitnset(M_RESTR, m->m_flags))
  885.         {
  886.             if (ctladdr == NULL || ctladdr->q_uid == 0)
  887.             {
  888.                 (void) setgid(DefGid);
  889.                 (void) initgroups(DefUser, DefGid);
  890.                 (void) setuid(DefUid);
  891.             }
  892.             else
  893.             {
  894.                 (void) setgid(ctladdr->q_gid);
  895.                 (void) initgroups(ctladdr->q_ruser?
  896.                     ctladdr->q_ruser: ctladdr->q_user,
  897.                     ctladdr->q_gid);
  898.                 (void) setuid(ctladdr->q_uid);
  899.             }
  900.         }
  901.  
  902.         /* arrange for all the files to be closed */
  903.         for (i = 3; i < DtableSize; i++) {
  904.             register int j;
  905.             if ((j = fcntl(i, F_GETFD, 0)) != -1)
  906.                 (void)fcntl(i, F_SETFD, j|1);
  907.         }
  908.  
  909.         /* try to execute the mailer */
  910.         execve(m->m_mailer, pvp, UserEnviron);
  911.         syserr("Cannot exec %s", m->m_mailer);
  912.         if (m == LocalMailer || errno == EIO || errno == EAGAIN ||
  913.             errno == ENOMEM || errno == EPROCLIM)
  914.             _exit(EX_TEMPFAIL);
  915.         else
  916.             _exit(EX_UNAVAILABLE);
  917.     }
  918.  
  919.     /*
  920.     **  Set up return value.
  921.     */
  922.  
  923.     (void) close(mpvect[0]);
  924.     mfile = fdopen(mpvect[1], "w");
  925.     if (clever)
  926.     {
  927.         (void) close(rpvect[1]);
  928.         rfile = fdopen(rpvect[0], "r");
  929.     } else
  930.         rfile = NULL;
  931.  
  932.     *pmfile = mfile;
  933.     *prfile = rfile;
  934.  
  935.     return (pid);
  936. }
  937. /*
  938. **  GIVERESPONSE -- Interpret an error response from a mailer
  939. **
  940. **    Parameters:
  941. **        stat -- the status code from the mailer (high byte
  942. **            only; core dumps must have been taken care of
  943. **            already).
  944. **        m -- the mailer descriptor for this mailer.
  945. **
  946. **    Returns:
  947. **        none.
  948. **
  949. **    Side Effects:
  950. **        Errors may be incremented.
  951. **        ExitStat may be set.
  952. */
  953.  
  954. giveresponse(stat, m, e)
  955.     int stat;
  956.     register MAILER *m;
  957.     ENVELOPE *e;
  958. {
  959.     register char *statmsg;
  960.     extern char *SysExMsg[];
  961.     register int i;
  962.     extern int N_SysEx;
  963. #ifdef NAMED_BIND
  964.     extern int h_errno;
  965. #endif
  966.     char buf[MAXLINE];
  967.  
  968. #ifdef lint
  969.     if (m == NULL)
  970.         return;
  971. #endif lint
  972.  
  973.     /*
  974.     **  Compute status message from code.
  975.     */
  976.  
  977.     i = stat - EX__BASE;
  978.     if (stat == 0)
  979.         statmsg = "250 Sent";
  980.     else if (i < 0 || i > N_SysEx)
  981.     {
  982.         (void) sprintf(buf, "554 unknown mailer error %d", stat);
  983.         stat = EX_UNAVAILABLE;
  984.         statmsg = buf;
  985.     }
  986.     else if (stat == EX_TEMPFAIL)
  987.     {
  988.         (void) strcpy(buf, SysExMsg[i]);
  989. #ifdef NAMED_BIND
  990.         if (h_errno == TRY_AGAIN)
  991.         {
  992.             extern char *errstring();
  993.  
  994.             statmsg = errstring(h_errno+MAX_ERRNO);
  995.         }
  996.         else
  997. #endif
  998.         {
  999.             if (errno != 0)
  1000.             {
  1001.                 extern char *errstring();
  1002.  
  1003.                 statmsg = errstring(errno);
  1004.             }
  1005.             else
  1006.             {
  1007. #ifdef SMTP
  1008.                 extern char SmtpError[];
  1009.  
  1010.                 statmsg = SmtpError;
  1011. #else SMTP
  1012.                 statmsg = NULL;
  1013. #endif SMTP
  1014.             }
  1015.         }
  1016.         if (statmsg != NULL && statmsg[0] != '\0')
  1017.         {
  1018.             (void) strcat(buf, ": ");
  1019.             (void) strcat(buf, statmsg);
  1020.         }
  1021.         statmsg = buf;
  1022.     }
  1023.     else
  1024.     {
  1025.         statmsg = SysExMsg[i];
  1026.     }
  1027.  
  1028.     /*
  1029.     **  Print the message as appropriate
  1030.     */
  1031.  
  1032.     if (stat == EX_OK || stat == EX_TEMPFAIL)
  1033.         message(Arpa_Info, &statmsg[4]);
  1034.     else
  1035.     {
  1036.         Errors++;
  1037.         usrerr(statmsg);
  1038.     }
  1039.  
  1040.     /*
  1041.     **  Final cleanup.
  1042.     **    Log a record of the transaction.  Compute the new
  1043.     **    ExitStat -- if we already had an error, stick with
  1044.     **    that.
  1045.     */
  1046.  
  1047.     if (LogLevel > ((stat == 0 || stat == EX_TEMPFAIL) ? 3 : 2))
  1048.         logdelivery(&statmsg[4]);
  1049.  
  1050.     if (stat != EX_TEMPFAIL)
  1051.         setstat(stat);
  1052.     if (stat != EX_OK)
  1053.     {
  1054.         if (e->e_message != NULL)
  1055.             free(e->e_message);
  1056.         e->e_message = newstr(&statmsg[4]);
  1057.     }
  1058.     errno = 0;
  1059. #ifdef NAMED_BIND
  1060.     h_errno = 0;
  1061. #endif
  1062. }
  1063. /*
  1064. **  LOGDELIVERY -- log the delivery in the system log
  1065. **
  1066. **    Parameters:
  1067. **        stat -- the message to print for the status
  1068. **
  1069. **    Returns:
  1070. **        none
  1071. **
  1072. **    Side Effects:
  1073. **        none
  1074. */
  1075.  
  1076. logdelivery(stat)
  1077.     char *stat;
  1078. {
  1079.     extern char *pintvl();
  1080.  
  1081. # ifdef LOG
  1082.     syslog(LOG_INFO, "%s: to=%s, delay=%s, stat=%s", CurEnv->e_id,
  1083.            CurEnv->e_to, pintvl(curtime() - CurEnv->e_ctime, TRUE), stat);
  1084. # endif LOG
  1085. }
  1086. /*
  1087. **  PUTFROMLINE -- output a UNIX-style from line (or whatever)
  1088. **
  1089. **    This can be made an arbitrary message separator by changing $l
  1090. **
  1091. **    One of the ugliest hacks seen by human eyes is contained herein:
  1092. **    UUCP wants those stupid "remote from <host>" lines.  Why oh why
  1093. **    does a well-meaning programmer such as myself have to deal with
  1094. **    this kind of antique garbage????
  1095. **
  1096. **    Parameters:
  1097. **        fp -- the file to output to.
  1098. **        m -- the mailer describing this entry.
  1099. **
  1100. **    Returns:
  1101. **        none
  1102. **
  1103. **    Side Effects:
  1104. **        outputs some text to fp.
  1105. */
  1106.  
  1107. putfromline(fp, m)
  1108.     register FILE *fp;
  1109.     register MAILER *m;
  1110. {
  1111.     char *template = "\001l\n";
  1112.     char buf[MAXLINE];
  1113.  
  1114.     if (bitnset(M_NHDR, m->m_flags))
  1115.         return;
  1116.  
  1117. # ifdef UGLYUUCP
  1118.     if (bitnset(M_UGLYUUCP, m->m_flags))
  1119.     {
  1120.         char *bang;
  1121.         char xbuf[MAXLINE];
  1122.  
  1123.         expand("\001g", buf, &buf[sizeof buf - 1], CurEnv);
  1124.         bang = index(buf, '!');
  1125.         if (bang == NULL)
  1126.             syserr("No ! in UUCP! (%s)", buf);
  1127.         else
  1128.         {
  1129.             *bang++ = '\0';
  1130.             (void) sprintf(xbuf, "From %s  \001d remote from %s\n", bang, buf);
  1131.             template = xbuf;
  1132.         }
  1133.     }
  1134. # endif UGLYUUCP
  1135.     expand(template, buf, &buf[sizeof buf - 1], CurEnv);
  1136.     putline(buf, fp, m);
  1137. }
  1138. /*
  1139. **  PUTBODY -- put the body of a message.
  1140. **
  1141. **    Parameters:
  1142. **        fp -- file to output onto.
  1143. **        m -- a mailer descriptor to control output format.
  1144. **        e -- the envelope to put out.
  1145. **
  1146. **    Returns:
  1147. **        none.
  1148. **
  1149. **    Side Effects:
  1150. **        The message is written onto fp.
  1151. */
  1152.  
  1153. putbody(fp, m, e)
  1154.     FILE *fp;
  1155.     MAILER *m;
  1156.     register ENVELOPE *e;
  1157. {
  1158.     char buf[MAXLINE];
  1159.  
  1160.     /*
  1161.     **  Output the body of the message
  1162.     */
  1163.  
  1164.     if (e->e_dfp == NULL)
  1165.     {
  1166.         if (e->e_df != NULL)
  1167.         {
  1168.             e->e_dfp = fopen(e->e_df, "r");
  1169.             if (e->e_dfp == NULL)
  1170.                 syserr("putbody: Cannot open %s for %s from %s",
  1171.                 e->e_df, e->e_to, e->e_from);
  1172.         }
  1173.         else
  1174.             putline("<<< No Message Collected >>>", fp, m);
  1175.     }
  1176.     if (e->e_dfp != NULL)
  1177.     {
  1178.         rewind(e->e_dfp);
  1179.         while (!ferror(fp) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
  1180.         {
  1181.             if (buf[0] == 'F' && bitnset(M_ESCFROM, m->m_flags) &&
  1182.                 strncmp(buf, "From ", 5) == 0)
  1183.                 (void) putc('>', fp);
  1184.             putline(buf, fp, m);
  1185.         }
  1186.  
  1187.         if (ferror(e->e_dfp))
  1188.         {
  1189.             syserr("putbody: read error");
  1190.             ExitStat = EX_IOERR;
  1191.         }
  1192.     }
  1193.  
  1194.     (void) fflush(fp);
  1195.     if (ferror(fp) && errno != EPIPE)
  1196.     {
  1197.         syserr("putbody: write error");
  1198.         ExitStat = EX_IOERR;
  1199.     }
  1200.     errno = 0;
  1201. }
  1202. /*
  1203. **  MAILFILE -- Send a message to a file.
  1204. **
  1205. **    If the file has the setuid/setgid bits set, but NO execute
  1206. **    bits, sendmail will try to become the owner of that file
  1207. **    rather than the real user.  Obviously, this only works if
  1208. **    sendmail runs as root.
  1209. **
  1210. **    This could be done as a subordinate mailer, except that it
  1211. **    is used implicitly to save messages in ~/dead.letter.  We
  1212. **    view this as being sufficiently important as to include it
  1213. **    here.  For example, if the system is dying, we shouldn't have
  1214. **    to create another process plus some pipes to save the message.
  1215. **
  1216. **    Parameters:
  1217. **        filename -- the name of the file to send to.
  1218. **        ctladdr -- the controlling address header -- includes
  1219. **            the userid/groupid to be when sending.
  1220. **
  1221. **    Returns:
  1222. **        The exit code associated with the operation.
  1223. **
  1224. **    Side Effects:
  1225. **        none.
  1226. */
  1227.  
  1228. mailfile(filename, ctladdr)
  1229.     char *filename;
  1230.     ADDRESS *ctladdr;
  1231. {
  1232.     register FILE *f;
  1233.     register int pid;
  1234.     ENVELOPE *e = CurEnv;
  1235.  
  1236.     /*
  1237.     **  Fork so we can change permissions here.
  1238.     **    Note that we MUST use fork, not vfork, because of
  1239.     **    the complications of calling subroutines, etc.
  1240.     */
  1241.  
  1242.     DOFORK(fork);
  1243.  
  1244.     if (pid < 0)
  1245.         return (EX_OSERR);
  1246.     else if (pid == 0)
  1247.     {
  1248.         /* child -- actually write to file */
  1249.         struct stat stb;
  1250.  
  1251.         (void) signal(SIGINT, SIG_DFL);
  1252.         (void) signal(SIGHUP, SIG_DFL);
  1253.         (void) signal(SIGTERM, SIG_DFL);
  1254.         (void) umask(OldUmask);
  1255.         if (stat(filename, &stb) < 0)
  1256.         {
  1257.             errno = 0;
  1258.             stb.st_mode = 0666;
  1259.         }
  1260.         if (bitset(0111, stb.st_mode))
  1261.             exit(EX_CANTCREAT);
  1262.         if (ctladdr == NULL)
  1263.             ctladdr = &e->e_from;
  1264.         /* we have to open the dfile BEFORE setuid */
  1265.         if (e->e_dfp == NULL &&  e->e_df != NULL)
  1266.         {
  1267.             e->e_dfp = fopen(e->e_df, "r");
  1268.             if (e->e_dfp == NULL) {
  1269.                 syserr("mailfile: Cannot open %s for %s from %s",
  1270.                 e->e_df, e->e_to, e->e_from);
  1271.             }
  1272.         }
  1273.  
  1274.         if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0)
  1275.         {
  1276.             if (ctladdr->q_uid == 0) {
  1277.                 (void) setgid(DefGid);
  1278.                 (void) initgroups(DefUser, DefGid);
  1279.             } else {
  1280.                 (void) setgid(ctladdr->q_gid);
  1281.                 (void) initgroups(ctladdr->q_ruser?
  1282.                     ctladdr->q_ruser: ctladdr->q_user,
  1283.                     ctladdr->q_gid);
  1284.             }
  1285.         }
  1286.         if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0)
  1287.         {
  1288.             if (ctladdr->q_uid == 0)
  1289.                 (void) setuid(DefUid);
  1290.             else
  1291.                 (void) setuid(ctladdr->q_uid);
  1292.         }
  1293.         f = dfopen(filename, "a");
  1294.         if (f == NULL)
  1295.             exit(EX_CANTCREAT);
  1296.  
  1297.         putfromline(f, ProgMailer);
  1298.         (*CurEnv->e_puthdr)(f, ProgMailer, CurEnv);
  1299.         putline("\n", f, ProgMailer);
  1300.         (*CurEnv->e_putbody)(f, ProgMailer, CurEnv);
  1301.         putline("\n", f, ProgMailer);
  1302.         (void) fclose(f);
  1303.         (void) fflush(stdout);
  1304.  
  1305.         /* reset ISUID & ISGID bits for paranoid systems */
  1306.         (void) chmod(filename, (int) stb.st_mode);
  1307.         exit(EX_OK);
  1308.         /*NOTREACHED*/
  1309.     }
  1310.     else
  1311.     {
  1312.         /* parent -- wait for exit status */
  1313.         int st;
  1314.  
  1315.         st = waitfor(pid);
  1316.         if ((st & 0377) != 0)
  1317.             return (EX_UNAVAILABLE);
  1318.         else
  1319.             return ((st >> 8) & 0377);
  1320.         /*NOTREACHED*/
  1321.     }
  1322. }
  1323. /*
  1324. **  SENDALL -- actually send all the messages.
  1325. **
  1326. **    Parameters:
  1327. **        e -- the envelope to send.
  1328. **        mode -- the delivery mode to use.  If SM_DEFAULT, use
  1329. **            the current SendMode.
  1330. **
  1331. **    Returns:
  1332. **        none.
  1333. **
  1334. **    Side Effects:
  1335. **        Scans the send lists and sends everything it finds.
  1336. **        Delivers any appropriate error messages.
  1337. **        If we are running in a non-interactive mode, takes the
  1338. **            appropriate action.
  1339. */
  1340.  
  1341. sendall(e, mode)
  1342.     ENVELOPE *e;
  1343.     char mode;
  1344. {
  1345.     register ADDRESS *q;
  1346.     bool oldverbose;
  1347.     int pid;
  1348.     FILE *lockfp = NULL, *queueup();
  1349.  
  1350.     /* determine actual delivery mode */
  1351.     if (mode == SM_DEFAULT)
  1352.     {
  1353.         extern bool shouldqueue();
  1354.  
  1355.         if (shouldqueue(e->e_msgpriority))
  1356.             mode = SM_QUEUE;
  1357.         else
  1358.             mode = SendMode;
  1359.     }
  1360.  
  1361.     if (tTd(13, 1))
  1362.     {
  1363.         printf("\nSENDALL: mode %c, sendqueue:\n", mode);
  1364.         printaddr(e->e_sendqueue, TRUE);
  1365.     }
  1366.  
  1367.     /*
  1368.     **  Do any preprocessing necessary for the mode we are running.
  1369.     **    Check to make sure the hop count is reasonable.
  1370.     **    Delete sends to the sender in mailing lists.
  1371.     */
  1372.  
  1373.     CurEnv = e;
  1374.  
  1375.     if (e->e_hopcount > MAXHOP)
  1376.     {
  1377.         errno = 0;
  1378.         syserr("sendall: too many hops %d (%d max): from %s, to %s",
  1379.             e->e_hopcount, MAXHOP, e->e_from, e->e_to);
  1380.         return;
  1381.     }
  1382.  
  1383.     if (!MeToo)
  1384.     {
  1385.         extern ADDRESS *recipient();
  1386.  
  1387.         e->e_from.q_flags |= QDONTSEND;
  1388.         (void) recipient(&e->e_from, &e->e_sendqueue);
  1389.     }
  1390.  
  1391. # ifdef QUEUE
  1392.     if ((mode == SM_QUEUE || mode == SM_FORK ||
  1393.          (mode != SM_VERIFY && SuperSafe)) &&
  1394.         !bitset(EF_INQUEUE, e->e_flags))
  1395.         lockfp = queueup(e, TRUE, mode == SM_QUEUE);
  1396. #endif QUEUE
  1397.  
  1398.     oldverbose = Verbose;
  1399.     switch (mode)
  1400.     {
  1401.       case SM_VERIFY:
  1402.         Verbose = TRUE;
  1403.         break;
  1404.  
  1405.       case SM_QUEUE:
  1406.         e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
  1407.         return;
  1408.  
  1409.       case SM_FORK:
  1410.         if (e->e_xfp != NULL)
  1411.             (void) fflush(e->e_xfp);
  1412.         pid = fork();
  1413.         if (pid < 0)
  1414.         {
  1415.             mode = SM_DELIVER;
  1416.             break;
  1417.         }
  1418.         else if (pid > 0)
  1419.         {
  1420.             /* be sure we leave the temp files to our child */
  1421.             e->e_id = e->e_df = NULL;
  1422.             if (lockfp != NULL)
  1423.                 (void) fclose(lockfp);
  1424.             return;
  1425.         }
  1426.  
  1427.         /* double fork to avoid zombies */
  1428.         if (fork() > 0)
  1429.             exit(EX_OK);
  1430.  
  1431.         /* be sure we are immune from the terminal */
  1432.         disconnect(FALSE);
  1433.  
  1434.         break;
  1435.     }
  1436.  
  1437.     /*
  1438.     **  Run through the list and send everything.
  1439.     */
  1440.  
  1441.     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  1442.     {
  1443.         if (mode == SM_VERIFY)
  1444.         {
  1445.             e->e_to = q->q_paddr;
  1446.             if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
  1447.                 message(Arpa_Info, "deliverable");
  1448.         }
  1449.         else
  1450.             (void) deliver(e, q);
  1451.     }
  1452.     Verbose = oldverbose;
  1453.  
  1454.     /*
  1455.     **  Now run through and check for errors.
  1456.     */
  1457.  
  1458.     if (mode == SM_VERIFY) {
  1459.         if (lockfp != NULL)
  1460.             (void) fclose(lockfp);
  1461.         return;
  1462.     }
  1463.  
  1464.     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  1465.     {
  1466.         register ADDRESS *qq;
  1467.  
  1468.         if (tTd(13, 3))
  1469.         {
  1470.             printf("Checking ");
  1471.             printaddr(q, FALSE);
  1472.         }
  1473.  
  1474.         /* only send errors if the message failed */
  1475.         if (!bitset(QBADADDR, q->q_flags))
  1476.             continue;
  1477.  
  1478.         /* we have an address that failed -- find the parent */
  1479.         for (qq = q; qq != NULL; qq = qq->q_alias)
  1480.         {
  1481.             char obuf[MAXNAME + 6];
  1482.             extern char *aliaslookup();
  1483.  
  1484.             /* we can only have owners for local addresses */
  1485.             if (!bitnset(M_LOCAL, qq->q_mailer->m_flags))
  1486.                 continue;
  1487.  
  1488.             /* see if the owner list exists */
  1489.             (void) strcpy(obuf, "owner-");
  1490.             if (strncmp(qq->q_user, "owner-", 6) == 0)
  1491.                 (void) strcat(obuf, "owner");
  1492.             else
  1493.                 (void) strcat(obuf, qq->q_user);
  1494.             makelower(obuf);
  1495.             if (aliaslookup(obuf) == NULL)
  1496.                 continue;
  1497.  
  1498.             if (tTd(13, 4))
  1499.                 printf("Errors to %s\n", obuf);
  1500.  
  1501.             /* owner list exists -- add it to the error queue */
  1502.             sendtolist(obuf, (ADDRESS *) NULL, &e->e_errorqueue);
  1503.             ErrorMode = EM_MAIL;
  1504.             break;
  1505.         }
  1506.  
  1507.         /* if we did not find an owner, send to the sender */
  1508.         if (qq == NULL && bitset(QBADADDR, q->q_flags))
  1509.             sendtolist(e->e_from.q_paddr, qq, &e->e_errorqueue);
  1510.     }
  1511.  
  1512.     /* this removes the lock on the file */
  1513.     if (lockfp != NULL)
  1514.         (void) fclose(lockfp);
  1515.  
  1516.     if (mode == SM_FORK)
  1517.         finis();
  1518. }
  1519.